EM20-DK 使用技术手册
一、概述
EM20-DK 是一款高性能的嵌入式开发板,适用于各种物联网和边缘计算应用。本手册旨在指导用户如何正确使用和配置 EM20-DK 开发板。
二、开机、关机和重启
2.1 开机
-
在提供开发板时,一般会同时提供一个制作好的 Micro SD 卡,该卡可以启动开发板。插入准备的 USB 转串口线,以太网线,Micro SD 卡,最后插入 12V 电源:
-
此时上电成功,电源指示灯和系统指示灯都亮起:
2.2 关机
开发板正常工作时,输入 shutdown 命令后,系统将按预设时序自动关机:
root@em20-dk:~# shutdown
Shutdown scheduled for Sat 2024-04-20 03:35:48 CST, use 'shutdown -c' to cancel.
root@em20-dk:~#
root@em20-dk:~#
root@em20-dk:~#
Stopping session-1.scope - Session 1 of User root...
[ OK ] Removed slice system-modprobe.slice - Slice /system/modprobe.
......
[ OK ] Finished systemd-poweroff.service - System Power Off.
[ OK ] Reached target poweroff.target - System Power Off.
[ 2811.790456] vipcore, destroy device start...
[ 2811.794956] resource: Trying to free nonexistent resource <0x00000001c0000000-0x000000043fffffff>
[ 2811.804764] vipcore, destroy device end...
[ 2811.810587] ES8388 2-0011: es8388 not initialized, skipping shutdown
[ 2811.818183] reboot: Power down
2.3 重启
开发板正常工作时,按下复位键即可重新启动。
三、启动方式
EM20-DK 支持多种启动方式,包括:
- 从 Micro SD 启动:预装有操作系统的 Micro SD
- 从 eMMC 启动: eMMC 设备经过镜像烧录后启动
- 从网络 PXE 启动: 预装有操作系统的 Micro SD 或 eMMC
- 从网络 NFS 启动: 预装有操作系统的 Micro SD 或 eMMC
3.1 Micro SD 启动
开发板出厂时通常会附带一张预装操作系统的 Micro SD 启动卡。该启动卡不仅能够启动开发板,还提供了一些比较基础的可执行程序。用户可以通过探索这些程序了解开发板的基本功能,从而建立对开发板和 SDK 的初步认知。
如需制作新的启动卡或替换现有启动卡,请按照以下步骤操作:
3.1.1 下载镜像
获取镜像的流程如下:
- 获取 SDK 镜像包。
- 选择
.img.xz格式的压缩镜像文件,先进行解压,生成.img镜像文件后用于烧录。
3.1.2 使用 balenaEtcher 烧录镜像
我们推荐使用 balenaEtcher 来烧录镜像,这是一款在 macOS、Windows 和 Linux 系统均可使用的镜像烧录工具。
烧录镜像的具体步骤如下图所示:
-
选择镜像
-
选择 SD 卡
-
开始烧录
-
烧录过程
烧录过程中界面如下。
烧录完成后会出现 正在验证 的界面。
💡 提示:
- 如果觉得验证比较耗时,可以点击“跳过”,不会影响烧录。
-
烧录完成
烧录完成后会出现 烧录成功 的提示界面。
3.1.3 检查启动卡
制作完烧录卡后,将卡插入 Ubuntu 系统,可以发现出现 2 个分区(bootfs 分区和 rootfs 分区),具体定义如下:
- 启动分区(盘符名 bootfs)
启动分区用于存储系统启动过程中所需的各类文件,包括引导程序、内核镜像等。该启动分区通常采用 FAT32 文件系统格式,以确保兼容性。启动分区包含的主要文件说明如下:
kernel.itb:内核镜像文件u-boot.itb:引导程序文件fw_jump.bin:固件文件(如果适用)
- 根文件系统分区(盘符名 rootfs)
根文件系统分区是 Micro SD 卡上用于存储操作系统核心文件的重要区域,是文件系统的最高层级目录,包括系统的命令库、配置文件、驱动程序等,根分区通常为 ext4 文件系统格式。
Code block
.
├── bin -> usr/bin # 存放系统的基础命令,如ls、cp、mv等
├── bin.usr-is-merged
├── boot
├── dev # 设备文件,用来与硬件交互
├── etc # 存放系统配置文件,如网络配置、用户配置等
├── home # 存放系统用户的家目录
├── lib -> usr/lib # 存放系统运行所需的共享库文件
├── lib.usr-is-merged
├── media
├── mnt
├── opt
├── proc
├── run
├── sbin -> usr/sbin # 存放系统管理命令
├── sbin.usr-is-merged
├── srv # 存放服务相关的文件
├── sys # 存放系统运行时的信息
├── tmp # 临时文件存放目录
├── usr # 用户应用程序和文件的存放目录
└── var # 存放系统运行时产生的可变数据
完成启动卡制作后,可以参考 「EM20-DK 使用技术手册」文档的「开机」章节 的相关内容启动开发套件。
📝 注意:
如果用户使用的是 Windows 操作系统,则无需手动管理这些分区,安装程序会自动设置,如果需要手动管理这些分区,可以采用 Windows 操作系统自带的磁盘管理工具进行管理。
3.2 eMMC 启动
需要制作一张 Micro SD 烧录卡,并把镜像正确烧录到 eMMC,具体烧录步骤可参考「EM20-DK 使用技术手册」文档的「Micro SD 卡烧录 eMMC 升级」章节 的相关内容。拔出 Micro SD ,按复位键重启即为 eMMC 启动。
3.3 网络 PXE 启动
需要制作一张 Micro SD 烧录卡或者已被正确烧录过的 eMMC,PXE 启动会在仅使用 Boot.fr 和 config.txt 的情况下通过网络去启动系统。
要从网络 PXE 启动,首先需要在电脑端配置 TFTP 和 NFS 服务器,然后开发板端完成配置并启动。
3.3.1 配置 TFTP 服务器
sudo apt-get install tftp-hpa tftpd-hpa
sudo apt-get install xinetd
sudo mkdir -p /pxe_server/tftp
sudo chmod 777 /pxe_server/tftp
修改 /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/pxe_server/tftp"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="-l -c -s"
创建 PXE 目录
sudo mkdir -p /pxe_server/tftp/pxelinux.cfg
创建 PXE 配置文件
在 pxelinux.cfg 目录下创建对应的 PXE 配置文件,文件名格式为 01-xx-xx-xx-xx-xx-xx,其中 01- 为固定字段,后面紧跟开发板的 MAC 地址。
例如,针对 MAC 地址为 e6:e8:dc:ff:db:da 的开发板,应创建文件 /pxe_server/tftp/pxelinux.cfg/01-e6-e8-dc-ff-db-da:
default Ubuntu Linux-6.6
menu title ULTIMATE PXE SERVER - By Griffon - Ver 1.0
prompt 0
timeout 0
label Ubuntu Linux-6.6
kernel kernel.itb#tps-ea65xx-dk-v3
initrd rootfs.cpio.uboot
复制镜像文件
将 Micro SD 卡 bootfs 分区文件 Boot.fr、fw_jump.bin、kernel.itb、rootfs.cpio.uboot、u-boot.itb、sapboot.fr 和 overlays 目录复制到 /pxe_server/tftp/ 目录下。在开发时可对应替换为自己的镜像文件。
启动 TFTP 服务器
sudo service tftpd-hpa restart
注意:针对不同开发板要烧录不同内核镜像和设备树,只需在
pxelinux.cfg目录下创建对应的 PXE 配置文件即可。
3.3.2 配置 NFS 服务器
安装 NFS 服务
sudo apt-get install nfs-kernel-server rpcbind
修改 /etc/exports,在文件末尾添加(注意:路径和 * 之间有个空格):
/srv/nfs/rootfs *(rw,sync,no_root_squash)
其中 /srv/nfs/rootfs 为 NFS 文件系统挂载路径。
修改 /etc/default/nfs-kernel-server,在文件末尾添加:
RPCNFSDOPTS="--nfs-version 2,3,4 --debug --syslog"
复制镜像文件
将 Micro SD 卡 rootfs 分区下所有文件及目录复制到 /srv/nfs/rootfs 目录下。在开发时可对应替换为自己定制的文件系统。
启动 NFS 服务
sudo systemctl restart nfs-kernel-server
3.3.3 配置开发板
完成服务器端配置后,需要在开发板端进行相应的网络启动参数配置。开发板通过修改 bootfs 分区下的 config.txt 文件来设置网络启动相关参数,具体配置示例如下:
# 使能PXE
force_pxe=true
# 从eth1启动
ethact=eth1
# 服务器IP地址
serverip=192.168.56.99
# NFS文件系统挂载路径
rootpath=/srv/nfs/rootfs
完成配置文件的修改后,重新上电即可通过网络启动系统。启动成功后,启动日志中会看到打印 Now switch to pxe boot 字样。关于 config.txt 文件中各配置变量的详细说明,请参考「BSP 开发技术手册」文档的「config.txt 使用说明」章节的相关内容。
3.4 网络 NFS 启动
网络 NFS 启动需要准备一张 Micro SD 烧录卡或已正确烧录的 eMMC 设备。NFS 启动会在挂载文件系统时通过网络去加载。开发板端需要修改 bootfs 分区下的 config.txt 文件,具体配置示例如下:
# 必须关闭PXE
force_pxe=false
# 从eth0启动
ethact=eth0
# 服务器IP地址
serverip=192.168.56.99
# NFS文件系统挂载路径
rootpath=/srv/nfs/rootfs
# 使能nfs
nfs=true
完成配置文件的修改后,重新上电即可通过网络挂载文件系统。关于 config.txt 文件中各配置变量的详细说明,请参考「BSP 开发技术手册」文档的「config.txt 使用说明」章节的相关内容。NFS 服务器搭建可参考上述 3.3.2 配置 NFS 服务器 的相关内容。
四、登录系统
4.1 串口登录
在 Windows 系统上,推荐使用 SecureCRT 或 MobaXterm 等常用串口工具,Ubuntu 系统中可以选择 tabby 等常见的串口工具。选择正确的串口(例如:COM3),设置波特率为 115200,并确保其他必要参数(如校验位)设置正确。不同的串口工具默认配置可能不同,以下是一些常见工具的配置示例:
- SecureCRT:在"连接设置"中选择"串行",设置"波特率"为 115200,数据位为 8,停止位为 1,无校验位,无流量控制。
- MobaXterm:在"终端" → "设置" → "串口"中,设置"波特率"为 115200,数据位为 8,停止位为 1,校验位为"无"。
系统启动后,初始用户名为tps,密码为 123456,root 账户密码为 root。登录成功后的终端如下所示。
Ubuntu 24.04 LTS em20-dk ttyPS0
em20-dk login: root
Password:
Welcome to Ubuntu 24.04 LTS (GNU/Linux 6.6.0 riscv64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
root@em20-dk:~#
4.2 SSH 登录
使用 SSH 客户端(如 PuTTY、MobaXterm)可以通过命令行登录设备。以下是使用 MobaXterm 客户端登录的步骤:
- 打开 MobaXterm。
- 在主界面点击 "Session" → "SSH"。
- 在弹出的窗口中,输入设备的 IP 地址。
- 点击 "OK" 开始连接。
- 输入用户名(如
root)和密码进行登录。
使用命令行登录时,请将 your_ip 替换为设备的实际 IP 地址:
ssh root@your_ip
📝 注意:
- 请先通过串口登录或查看路由器 DHCP 分配列表获取设备的实际 IP 地址,然后用该地址替换上述命令中的
your_ip。
五、网络配置
5.1 获取 IP 地址
系统默认使用 DHCP 自动获取 IP 地址。如需获取设备的 IP 地址,请使用 ifconfig 命令:
root@em20-dk:~# ifconfig
...
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.56.220 netmask 255.255.254.0 broadcast 192.168.57.255
inet6 fe80::ffcb:7fab:c1f1:7ba prefixlen 64 scopeid 0x20<link>
ether ea:97:b3:36:a8:8a txqueuelen 1000 (Ethernet)
RX packets 261813 bytes 88985717 (88.9 MB)
RX errors 1023 dropped 9198 overruns 0 frame 1023
TX packets 66161 bytes 4517331 (4.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 32
...
此时 eth1 的 IP 地址为 192.168.56.220。
5.2 配置静态 IP
在配置静态 IP 之前,需要选择一个未被使用的 IP 地址,可以通过 ping 命令检查某个 IP 地址是否已经被使用。
如需手动配置静态 IP,请修改 /etc/netplan/01-network-manager-all.yaml 配置文件。以下是一个示例配置文件:
network:
version: 2
renderer: NetworkManager
ethernets:
eth1:
dhcp4: no
addresses:
- 192.168.56.4/24
optional: yes
dhcp-identifier: mac
routes:
- to: default
via: 192.168.57.254
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
eth2:
dhcp4: no
addresses:
- 192.168.56.5/24
optional: yes
dhcp-identifier: mac
routes:
- to: default
via: 192.168.57.254
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
保存文件后,执行以下命令应用配置:
netplan apply
这将为 eth1 和 eth2 配置静态 IP 地址。
5.3 验证配置
可通过 ifconfig 命令查看配置文件中定义的 IP 地址是否已激活。
5.4 动态 IP 配置
设置动态 IP 之前,需要先将 /etc/netplan/01-network-manager-all.yaml 文件中的静态 IP 配置注释掉,然后再进行配置:
network:
version: 2
renderer: NetworkManager
# ethernets:
# eth1:
# dhcp4: no
# addresses:
# - 192.168.56.4/24
# optional: yes
# dhcp-identifier: mac
# routes:
# - to: default
# via: 192.168.57.254
# nameservers:
# addresses:
# - 8.8.8.8
# - 8.8.4.4
# eth2:
# dhcp4: no
# addresses:
# - 192.168.56.5/24
# optional: yes
# dhcp-identifier: mac
# routes:
# - to: default
# via: 192.168.57.254
# nameservers:
# addresses:
# - 8.8.8.8
# - 8.8.4.4
保存文件后,执行以下命令应用配置更改:
sudo netplan apply
使用系统命令训练 ETH PHY 参数,具体步骤如下:
- 执行
tps-eth --list查询系统识别的网络:
root@em20-dk:~# tps-eth --list
Net name needed to adjust delay line:
eth1
eth2
- 选择训练某个 ETH 网口:
root@em20-dk:~# tps-eth eth1
MAC: a6:fa:7d:47:ee:62
Speed: 1000Mbps
Elapsed time: 3126 ms
Continuous cnt and location, tx: 58 71, rx: 47 46
Proper tx and rx: 42, 22
- 输入
systemctl restart NetworkManager来立即获取 IP,使用ifconfig或ip a命令检查 IP 地址:
root@em20-dk:~# systemctl restart NetworkManager
root@em20-dk:~# ifconfig
eth1: flags=4163 mtu 1500
inet 192.168.56.220 netmask 255.255.254.0 broadcast 192.168.57.255
inet6 fe80::ffcb:7fab:c1f1:7ba prefixlen 64 scopeid 0x20
ether ea:97:b3:36:a8:8a txqueuelen 1000 (Ethernet)
RX packets 261813 bytes 88985717 (88.9 MB)
RX errors 1023 dropped 9198 overruns 0 frame 1023
TX packets 66161 bytes 4517331 (4.5 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 32
六、系统升级
系统升级是指将操作系统和系统软件从当前版本更新至新版本的过程,新版本通常会提供一些新功能、安全补丁和性能改进。不同产品类型对系统升级方式的需求存在差异,目前 SDK 支持(或计划支持)多种升级方式,包括 Micro SD 卡烧录 eMMC 升级、文件替换升级等,以下将分别进行详细说明。
6.1 Micro SD 卡烧录 eMMC 升级
请参考 「EM20-DK 使用技术手册」文档的「启动方式」章节的 Micro SD 启动 制作一张 Micro SD 启动卡。制作完成后,需要修改 bootfs 分区中的 config.txt 配置文件,将启动卡转换为烧录卡模式,具体配置修改如下:
# boot_mode=initramfs
boot_mode=burn
完成配置修改后,插入 Micro SD 卡后按复位键重启设备,就可以在串口终端上看到系统启动并执行 eMMC 烧录的完整过程:
Starting burn.mmc0: /dev/mmcblk1 fs info saved in /tmp/tmp.burnZ9k6kf
Copy raw: /dev/mmcblk1 -> /dev/mmcblk0, 6144 bytes...
6144+0 records in
6144+0 records out
Copy raw: /dev/mmcblk1 -> /dev/mmcblk0 success
src: /dev/mmcblk1p1:vfat:bootfs -> /dev/mmcblk0p1:vfat:bootfs
mkfs.fat 4.2 (2021-01-31)
Cannot initialize conversion from codepage 850 to ANSI_X3.4-1968: Invalid argument
Cannot initialize conversion from ANSI_X3.4-1968 to codepage 850: Invalid argument
Using internal CP850 conversion table
mkfs.fat: Warning: lowercase labels might not work properly on some systems
src: /dev/mmcblk1p2:ext4:rootfs -> /dev/mmcblk0p2:ext4:rootfs
mke2fs 1.47.0 (5-Feb-2023)
Discarding device blocks: 0/262144 done
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: 3e680df8-1dd2-11b2-821b-5d4456229a89
Superblock backups stored on blocks:
32768, 98304, 163840, 229376
Allocating group tables: 0/8 done
Writing inode tables: 0/8 done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: 0/8 done
Copy /dev/mmcblk1p1 -> /dev/mmcblk0p1...
Copy /dev/mmcblk1p1 -> /dev/mmcblk0p1 success.
Copy /dev/mmcblk1p2 -> /dev/mmcblk0p2...
Copy /dev/mmcblk1p2 -> /dev/mmcblk0p2 success.
boot_mode found, force set to "boot"!
100000+0 records in
100000+0 records out
烧录过程通常需要数分钟时间,完成后即不再需要 Micro SD 卡,当系统有如下打印时,可直接拔除 Micro SD 卡,系统会自动重启:
Waiting for SD card to be removed...
📝 注意:
烧录完成后 Ubuntu 系统第一次启动时会进行文件系统初始化等关键动作,此过程大概持续几分钟左右,期间请勿随意断电。
6.2 文件替换升级
在少数场景下可以采用手动替换文件的方式对系统进行升级,例如需要快速修复系统关键文件等情况。这种升级方式存在数据丢失、硬件损坏等一系列风险,所以一般仅局限于特殊场景下使用,建议由接受过原厂专业培训的人员进行操作或者提供技术指导。
文件替换操作需要在开发板上的 Ubuntu 系统环境下执行,用户可以通过串口工具登录到开发板,然后根据实际需求选择合适的操作方式。
6.2.1 备份原文件
在进行文件替换之前,建议备份所有关键文件,以防升级过程中出现问题能够恢复到原始状态。
6.2.2 替换镜像
EM20-DK 平台启动后,将新的镜像文件上传至开发板的 /boot 目录下替换原有文件即可。文件上传的具体方法取决于用户的网络环境和开发板配置。以下是两种常见的上传方法:
- 通过 SCP 上传: 使用 SCP(Secure Copy Protocol)可以从本地计算机安全地复制文件到远程服务器。命令格式如下:
scp /path/to/new/kernel.itb root@ip:/boot/firmware
其中 /path/to/new/kernel.itb 是本地新镜像文件的路径,root@ip 是远程开发板的用户名和 IP 地址。将文件替换好后重启生效。
- 通过 USB 设备上传:
将 Micro SD 启动卡通过 USB 设备连接到电脑,使用
cp命令将镜像文件复制文件到 Micro SD 卡的/bootfs目录中。
cp /path/to/new/kernel.itb /run/media/bootfs
然后将替换好镜像的 Micro SD 卡重新插入开发板并启动。
6.2.3 验证升级
文件替换完成后,可以通过以下方法验证升级是否成功:
- 重启开发板,检查是否能够正常启动。
- 检查关键文件的版本信息,确认已更新到新版本。
七、系统使用说明
7.1 使用 GPIO
EA65xx 芯片支持三组 GPIO,分别命名为 SAP GPIO、CPU GPIO 和 RTC GPIO。在每个 GPIO 组内对信号从 0 开始编址,称为物理编号,此外,软件还对全部 GPIO 信号做了统一编址,称为逻辑编号,其编号规则是:
GPIO 逻辑编号 = GPIO 所属组 BASE 号 + 组内物理编号
其中,三个组的 BASE 号分别为 0、200、400。BASE 号的来源是根据 GPIO 组的命名和系统设计而定,以确保逻辑编号的唯一性和可识别性。于是,根据上述规则,GPIO 与 Linux 设备节点的对应关系如下表所示:
| GPIO 组别 | Linux 设备节点 | 物理编号范围 | 逻辑编号范围 |
|---|---|---|---|
| SAP GPIO | /sys/class/gpio/gpiochip0/ | 0 到 33 | 0 到 33 |
| CPU GPIO | /sys/class/gpio/gpiochip200/ | 0 到 142 | 200 到 342 |
| RTC GPIO | /sys/class/gpio/gpiochip400/ | 0 到 7 | 400 到 407 |
以 GPIO29 为例,它属于 SAP 组的原因是其逻辑编号为 29,根据逻辑编号计算规则,29 落在 SAP 组的逻辑编号范围内(0 到 33)。要正确判断 GPIO 的归属,可以根据其逻辑编号与上述表格中的逻辑编号范围进行匹配,可以通过以下命令进行操作:
- 导出 GPIO:将 GPIO 节点导出到
/sys/class/gpio/export。
echo 239 > /sys/class/gpio/export
- 设置 GPIO 方向:设置为输入或输出。
echo out > /sys/class/gpio/gpio239/direction
- 读写 GPIO 值
echo 1 > /sys/class/gpio/gpio239/value # 设置为高电平
cat /sys/class/gpio/gpio239/value # 读取当前值
7.2 使用 UART
EM20-DK 开发板提供了 12 组 UART,其中,EM20-DK 对外支持 UART0 已用作 bootloader 和 Linux 的 console 端口; UART5 用户可看情况配置使用。其他 UART 的可用性取决于具体的硬件设计和配置。用户可以通过以下命令测试 UART 通信:
root@em20-dk:~# echo "Hello World" > /dev/ttyPS0
Hello World
ttyPS0 为相应的 UART 设备文件,有 ttyPS0、ttyPS1、ttyPS2 等。如果 UART 不可用,可能是因为硬件设计或配置问题。
以下是一个示例代码,展示如何配置和使用 UART:
int set_interface_attribs(int fd, int speed, int hwfc) {
struct termios tty;
if (tcgetattr(fd, &tty) != 0) {
perror("tcgetattr");
return -1;
}
cfsetospeed(&tty, speed);
cfsetispeed(&tty, speed);
tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
tty.c_iflag &= ~IGNBRK;
tty.c_lflag = 0;
tty.c_oflag = 0;
tty.c_cc[VMIN] = 0;
tty.c_cc[VTIME] = 5;
tty.c_iflag &= ~(IXON | IXOFF | IXANY);
tty.c_cflag |= (CLOCAL | CREAD);
tty.c_cflag &= ~(PARENB | PARODD);
tty.c_cflag &= ~CSTOPB;
if (hwfc) {
tty.c_cflag |= CRTSCTS; // Enable hardware flow control
} else {
tty.c_cflag &= ~CRTSCTS;
}
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
perror("tcsetattr");
return -1;
}
return 0;
}
void set_blocking(int fd, int should_block) {
struct termios tty;
memset(&tty, 0, sizeof tty);
if (tcgetattr(fd, &tty) != 0) {
perror("tcgetattr");
return;
}
tty.c_cc[VMIN] = should_block ? 1 : 0;
tty.c_cc[VTIME] = 5;
if (tcsetattr(fd, TCSANOW, &tty) != 0)
perror("tcsetattr");
}
int rs485_send_test() {
int fd = open(rs485_port.c_str(), O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
perror("open RS485 port failed");
return -1;
}
if (set_interface_attribs(fd, rs485_baudrate, 0) != 0) {
close(fd);
return -1;
}
set_blocking(fd, 0);
std::string full_data = rs485_test_data + "\r\n";
int ret = write(fd, full_data.c_str(), full_data.length());
if (ret < 0) {
perror("RS485 write failed");
close(fd);
return -1;
}
DEBUG_INFO("Sent %d bytes: %s", ret, full_data.c_str());
close(fd);
return 0;
}
功能说明:
set_interface_attrs函数用于配置 UART 接口属性,如波特率、数据位、停止位、校验位等。set_blocking函数用于设置 UART 接口的阻塞模式。rs485_send_test函数用于打开指定的 UART 端口,配置其属性,并通过该端口发送数据。
通过上述代码,用户可以配置 UART 接口并通过该接口发送数据。具体配置和功能取决于实际的硬件设计和需求。
7.3 使用 I2C
提供了 8 路 I2C,可以使用标准的 I2C tools 和 API 操作。
i2cdetect命令输出已安装 I2C 总线的列表:
root@em20-dk:~# i2cdetect -l
i2c-0 i2c Cadence I2C at d2400000 I2C adapter
i2c-1 i2c Cadence I2C at d2401000 I2C adapter
i2c-2 i2c Cadence I2C at c2400000 I2C adapter
i2c-3 i2c Cadence I2C at c2401000 I2C adapter
i2c-4 i2c Cadence I2C at c2402000 I2C adapter
i2cset配置 I2C 外设
i2cset -f -y $I2C_BUS $I2C_ADDR $reg $value
i2cget获取 I2C 外设的值
i2cget -f -y $I2C_BUS $I2C_ADDR $reg w
参数解释:
- $I2C_BUS:I2C 总线号。
- $I2C_ADDR:I2C 设备的地址。
- $reg:寄存器地址。
- $value:要写入的值。
以下为一个示例,展示如何使用 i2cset 和 i2cget 命令:
# 设置 I2C 设备寄存器值
i2cset -f -y 1 0x50 0x00 0x01
# 获取 I2C 设备寄存器值
i2cget -f -y 1 0x50 0x00
7.4 使用 PWM
PWM(脉冲宽度调制)是一种常用的信号生成技术,用于控制模拟信号的占空比。操作 PWM 的示例如下:
- 启用 PWM:
echo 0 > /sys/class/pwm/pwmchip0/export
每个 PWM 通道下有以下文件:
period:设置 PWM 周期,单位为纳秒(ns)。duty_cycle:设置 PWM 占空比。enable:启用或禁用 PWM 通道。
- 配置 PWM:
echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/period # 设置 PWM 周期为 1ms
echo 500000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle # 设置 PWM 占空比
这表明设置 PWM0 的周期为 1ms,占空比为 50%。
- 使能 PWM:
echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable
7.5 查询硬件温度
使用命令 cat /sys/class/thermal/thermal_zone0/temp 获取 SoC 芯片温度。该命令返回的温度数值单位为毫摄氏度(mC)。
root@em20-dk:~# cat /sys/class/thermal/thermal_zone0/temp
26816
上述命令返回的数值 26816 表示芯片温度为 26.816°C。
使用命令 cat /sys/class/thermal/thermal_zone1/temp 获取核心板温度。该命令返回的温度数值单位同样为毫摄氏度(mC)。
root@em20-dk:~# cat /sys/class/thermal/thermal_zone1/temp
30250
7.6 查询内存信息
EM20-DK 板载了 16GB DDR,可以分为三类:
- OS 管理的部分,即可以用
malloc、kmalloc等常规 API 分配出来使用。
root@em20-mes20:~# free -h
total used free shared buff/cache available
Mem: 9.6Gi 268Mi 9.3Gi 1.1Mi 121Mi 9.4Gi
Swap: 0B 0B 0B
- taco-sys 管理的部分,预留给 NPU、VENC、VDEC 使用,需要使用
libtacosys.so库接口使用,可通过启动介质中bootfs分区里config.txt配置(默认值是2G),可以按需修改:
########## Memory Configuration ##########
# Uncomment this to set tacosys memory address to 0x140000000,
# and size to 0x80000000 bytes (2GiB)
# tacosys_mem_addr=0x140000000
# tacosys_mem_size=0x80000000
下面是一些使用 libtacosys 接口的实例代码,调用 npu_usage_t 和 cpu_usage_t 结构体来获取使用情况:
taco_npu_usage_t npu_usage = {0};
if (taco_sys_get_npu_usage(&npu_usage) == TACO_SUCCESS) {
printf("NPU Usage: %d%%\n", npu_usage.npu_usage);
} else {
printf("Failed to get NPU usage\n");
}
taco_cpu_usage_t cpu_usage = {0};
if (taco_sys_get_cpu_usage(&cpu_usage) == TACO_SUCCESS) {
printf("Total CPU Usage: %d%%\n", cpu_usage.total_cpu_usage);
for (int i = 0; i < 8; i++) {
printf("CPU%d Usage: %d%%\n", i, cpu_usage.cpu_usage[i]);
}
} else {
printf("Failed to get CPU usage\n");
}
- NPU 管理的部分,专门预留给 NPU(下面所示是注释掉的默认值),可以按需修改:
# Uncomment this to set npu memory address to 0x1c0000000,
# and size to 0x280000000 bytes (10GiB)
# npu_mem_addr=0x1c0000000
# npu_mem_size=0x280000000
这些命令将显示 tacosys 和 NPU 内存的实际分配情况。要验证配置是否生效,可以通过重启设备并再次检查这些文件的内容。
八、HDMI扩展板
8.1 概述
HDMI CONV 扩展板是一款专为 EM20-DK 开发板设计的单板双功能音视频接口扩展模块,支持 HDMI 转 USB UVC 采集 与 RGB 转 HDMI 显示输出 两种功能。
该扩展板通过标准 40Pin 树莓派兼容连接器与 EM20-DK 开发板对接,可广泛应用于视频采集、图像显示、视频环回处理等场景。其主要特性如下:
-
HDMI IN 功能:将外部设备(电脑、摄像头、机顶盒等)输入的 HDMI 音视频信号转换为标准 USB UVC 视频流,经 USB 3.0 接口传输至 EM20-DK 开发板,供实时预览、采集与 AI 处理。
-
HDMI OUT 功能:将 EM20-DK 开发板输出的 RGB 并行视频信号编码为标准 HDMI 信号,通过 HDMI OUT 接口驱动外部显示设备。
扩展板尺寸为 66.3mm × 58.5mm × 27mm,支持最大输入分辨率 4096×2160@60Hz(YUV420)和最大输出分辨率 3840×2160@30Hz(4K@30Hz)。
8.2 硬件接口
8.2.1 连接前检查
在进行扩展板连接前,请确认以下事项:
-
EM20-DK 开发板供电正常(12V 电源适配器),无异常复位现象。
-
40Pin 连接器方向正确,确保插接牢固,避免反插、偏插或未插到位。
-
HDMI 扩展板无明显短路、器件松动或接口损伤。
-
USB 3.0 数据线、HDMI 线缆和 FPC 软排线完好无损,连接器接触良好。
8.2.2 板间连接
将 HDMI 扩展板的 40Pin 母头连接器与 EM20-DK 开发板的 40Pin 公头连接器正确对接,确保插接到位且方向一致。扩展板将通过 40Pin 连接器从 EM20-DK 获取 5V 和 3.3V 电源。
8.2.3 HDMI IN 硬件环境搭建
-
使用标准 HDMI 线缆,将外部设备(如电脑、摄像头、机顶盒等)的 HDMI 输出接口连接至 HDMI 扩展板的 HDMI IN 接口。
-
使用 USB 3.0 公对公数据线,将 HDMI 扩展板的 USB 3.0 接口 连接至 EM20-DK 开发板的 USB 3.0 接口。
-
EM20-DK 上电后,系统将自动识别 UVC 设备,可通过视频采集应用程序(如 ffmpeg、gstreamer)进行视频预览与采集。
8.2.4 HDMI OUT 硬件环境搭建
-
使用 FPC 软排线,分别连接 HDMI 扩展板的 FPC 接口与 EM20-DK 开发板的 FPC 接口。插接时请注意排线方向和锁扣状态,确保连接牢固。
-
使用标准 HDMI 线缆,将 HDMI 扩展板的 HDMI OUT 接口连接至外部显示器。
-
EM20-DK 上电后,可通过系统配置将显示输出路由至 HDMI OUT 接口,驱动外部显示器。
8.3 功能使用说明
8.3.1 HDMI IN(UVC 采集)
EM20-DK 系统自带 UVC 驱动,扩展板连接后可通过以下方式验证采集功能:
查看设备节点:
ls /dev/video*
正常情况下会看到新增的 /dev/videoX 节点(如 /dev/video0)。
使用 ffmpeg 预览:
ffplay /dev/video0
使用 gstreamer 采集:
gst-launch-1.0 v4l2src device=/dev/video0 ! autovideosink
8.3.2 HDMI OUT(显示输出)
HDMI OUT 功能由 EM20-DK 的 RGB 并行视频接口驱动。在系统启动后,可通过以下方式配置显示输出:
-
确认 FPC 连接正常,外部显示器已开机并切换至对应 HDMI 输入源。
-
根据显示需求配置输出分辨率。系统默认输出为 1080p@30Hz,可通过修改设备树或应用层配置进行调整。
-
运行图形应用程序(如 Qt 应用、Wayland 或 X11 桌面),即可在外部显示器上看到输出画面。
九、系统工具说明
系统支持各式命令来辅助用户更方便的使用,以下是主要命令:
9.1 tps-version
获取软件版本。
root@em20-dk:~# tps-version
FFmpeg: 4.3.2-2.0.0
OpenCV: 4.5.4-2.0.0
TACO version: 2.0.0
U-Boot: U-Boot 2020.01 (Jul 10 2026 - 11:06:50 +0000)
Kernel version: Linux em20-dk 6.6.0-tps #2 SMP Fri Jul 10 11:05:28 UTC 2026 riscv64 riscv64 riscv64 GNU/Linux
HWversion: tps em20-dk
MCUversion (marchid): 0x80000000090c0d00
9.2 lsblk
要获取系统中的分区信息,可以使用 lsblk 命令。该命令将列出所有可用的块设备及其分区。
root@em20-dk:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
mmcblk0 179:0 0 29.1G 0 disk
├─mmcblk0p1 179:1 0 1G 0 part
└─mmcblk0p2 179:2 0 28.1G 0 part
mmcblk0boot0 179:8 0 8M 1 disk
mmcblk0boot1 179:16 0 8M 1 disk
mmcblk1 179:24 0 59.5G 0 disk
├─mmcblk1p1 179:25 0 1G 0 part /boot/firmware
└─mmcblk1p2 179:26 0 58.5G 0 part /
分区信息解释:
- mmcblk0:这是一个磁盘设备,总大小为 29.1 GB。它包含两个分区:
- mmcblk0p1:这是 mmcblk0 的第一个分区,大小为 1 GB,类型为 part(分区)。
- mmcblk0p2:这是 mmcblk0 的第二个分区,大小为 28.1 GB,类型为 part(分区)。
- mmcblk0boot0:这是一个磁盘设备,大小为 8 MB。它包含一个分区:
- mmcblk0boot1:这是 mmcblk0boot0 的分区,大小为 8 MB,类型为 disk(磁盘)。
- mmcblk1:这是另一个磁盘设备,总大小为 59.5 GB。它包含两个分区:
- mmcblk1p1:这是 blk1 的第一个分区,大小为 1 GB,类型为 part(分区),挂载点为
/boot/firmware,这通常用于存放启动固件或引导程序。 - mmcblk1p2:这是 blk1 的第二个分区,大小为 58.5 GB,类型为 part(分区),挂载点为
/,这是根文件系统所在的分区。
- mmcblk1p1:这是 blk1 的第一个分区,大小为 1 GB,类型为 part(分区),挂载点为
9.3 tps-smi
以 UI 的形式实时显示版本信息、时间、风扇转速、NPU 时钟频率、NPU 利用率、CPU 时钟频率、CPU 利用率等。
root@em20-dk:~# tps-smi
Wed Jul 15 15:53:19 2026
+-----------------------------------------------------------------------------+
| TPS SMI: 1.7.0 Firmware Version: 1.7.0 TACO Version: 2.0.0 |
+---------------------------------------+-------------------------------------+
| NPU-SOM SoC-Name |CPU-CurClk CPU-Usage Mem-Usage | SOM-Current SOM-Pwr |
|Fan ChipTemp SOM-Temp |NPU-Usage0 NPU-Usage1 NPU-Clk | SOM-SN |
| - TOPSFuture EA6530|1584MHz 0% 29% | 40mA 0mW |
|0 30°C 30°C| 0% 0% N/A | EM04CSC1A |
+---------------------------------------+-------------------------------------+
使用 Ctrl+C 退出界面。
十、常见问题
10.1 无法开机
问题描述: 设备无法正常启动。
原因分析:
- 电源适配器可能不兼容或损坏
- 电源连接不稳定或接触不良
解决方案:
- 检查电源连接状态,确认电源线和适配器完好无损
- 尝试使用不同的电源适配器,确保其输出电压和电流符合设备规格要求(例如: 12V,3A)
- 检查电源插座是否工作正常,尝试更换插座
10.2 无法登录系统
问题描述: 无法通过串口或 SSH 方式登录系统。
原因分析:
- 用户名或密码输入错误
- 网络连接异常导致 SSH 连接失败
解决方案:
- 确认用户名和密码是否正确:
- 默认用户名为
tps,密码为123456 root账户密码为root
- 默认用户名为
- 检查网络连接状态,确保开发板与计算机处于同一网络环境中
- 使用 SecureCRT 或 MobaXterm 等串口工具,配置正确的串口参数(如波特率设置为 115200)
10.3 系统升级失败
问题描述: 系统升级过程中出现异常,无法顺利完成升级操作。
原因分析:
- 升级包可能不完整或已损坏
- 网络连接问题导致下载过程中断
解决方案:
- 验证升级包的完整性,检查文件大小并进行 MD5 校验和验证
- 尝试重新下载升级包
- 确保网络连接稳定可靠,避免在升级过程中出现连接中断情况